home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH16 / ASM.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-03-26  |  11.5 KB  |  653 lines

  1. ; ASM.ASM
  2. ;
  3. ; This is a simple, single line, mini-assembler for an earlier
  4. ; version of the x86 processor. It converts strings containing valid 
  5. ; (old) x86 assembly code into a sequence of hex values corresponding 
  6. ; to the opcode and operands for the given instruction.
  7.  
  8.         .xlist
  9.         include     stdlib.a
  10.         matchfuncs
  11.         includelib    stdlib.lib
  12.         .list
  13.  
  14.  
  15.  
  16.  
  17. dseg        segment    para public 'data'
  18.  
  19.  
  20. ; Some sample statements to assemble:
  21.  
  22. Str1        byte    "load ax, 0",0
  23. Str2        byte    "load ax, bx",0
  24. Str3        byte    "load ax, ax",0
  25. Str4        byte    "add ax, 15",0
  26. Str5        byte    "sub ax, [bx]",0
  27. Str6        byte    "store bx, [1000]",0
  28. Str7        byte    "load bx, 2000[bx]",0
  29. Str8        byte    "goto 3000",0
  30. Str9        byte    "iflt ax, bx, 100",0
  31. Str10        byte    "halt",0
  32. Str11        byte    "This is illegal",0
  33. Str12        byte    "load ax, store",0
  34. Str13        byte    "store ax, 1000",0
  35. Str14        byte    "ifeq ax, 0, 0",0
  36.  
  37.  
  38.  
  39. ; Variables used by the assembler.
  40.  
  41. AsmConst    dw    0
  42. AsmOpcode    db    0
  43. AsmOprnd1    db    0
  44. AsmOprnd2    db    0
  45.  
  46.  
  47.  
  48.         include    stdsets.a    ;Bring in the standard char sets.
  49.  
  50.  
  51.  
  52. ; Patterns for the assembler:
  53.  
  54. ; Pattern is (
  55. ;           (load|store|add|sub) reg "," operand |
  56. ;           (ifeq|iflt|ifgt) reg1 "," reg2 "," const |
  57. ;           (get|put) operand |
  58. ;           goto operand |
  59. ;           halt
  60. ;         )
  61. ;
  62. ; With a few semantic additions (e.g., cannot store to a const).
  63.  
  64. InstrPat    pattern    {spancset, WhiteSpace,Grp1,Grp1}
  65.  
  66. Grp1        pattern    {sl_Match2,Grp1Strs, Grp2 ,Grp1Oprnds}
  67. Grp1Strs    pattern    {TryLoad,,Grp1Store}
  68. Grp1Store    pattern    {TryStore,,Grp1Add}
  69. Grp1Add        pattern    {TryAdd,,Grp1Sub}
  70. Grp1Sub        pattern    {TrySub}
  71.  
  72. ; Patterns for the LOAD, STORE, ADD, and SUB instructions.
  73.  
  74. LoadPat        pattern    {MatchStr,LoadInstr2}
  75. LoadInstr2    byte    "LOAD",0
  76.  
  77. StorePat    pattern    {MatchStr,StoreInstr2}
  78. StoreInstr2    byte    "STORE",0
  79.  
  80. AddPat        pattern    {MatchStr,AddInstr2}
  81. AddInstr2    byte    "ADD",0
  82.  
  83. SubPat        pattern    {MatchStr,SubInstr2}
  84. SubInstr2    byte    "SUB",0
  85.  
  86. ; Patterns for the group one (LOAD/STORE/ADD/SUB) instruction operands:
  87.  
  88. Grp1Oprnds    pattern    {spancset,WhiteSpace,Grp1reg,Grp1reg}
  89. Grp1Reg        pattern    {MatchReg,AsmOprnd1,,Grp1ws2}
  90. Grp1ws2        pattern    {spancset,WhiteSpace,Grp1Comma,Grp1Comma}
  91. Grp1Comma    pattern    {MatchChar,',',0,Grp1ws3}
  92. Grp1ws3        pattern    {spancset,WhiteSpace,Grp1Op2,Grp1Op2}
  93. Grp1Op2        pattern    {MatchGen,,,EndOfLine}
  94. EndOfLine    pattern    {spancset,WhiteSpace,NullChar,NullChar}
  95. NullChar    pattern    {EOS}
  96.  
  97. Grp1Op2Reg    pattern    {MatchReg,AsmOprnd2}
  98.  
  99.  
  100.  
  101. ; Patterns for the group two instructions (IFEQ, IFLT, IFGT):
  102.  
  103. Grp2        pattern    {sl_Match2,Grp2Strs, Grp3 ,Grp2Oprnds}
  104. Grp2Strs    pattern    {TryIFEQ,,Grp2IFLT}
  105. Grp2IFLT    pattern    {TryIFLT,,Grp2IFGT}
  106. Grp2IFGT    pattern    {TryIFGT}
  107.  
  108. Grp2Oprnds    pattern    {spancset,WhiteSpace,Grp2reg,Grp2reg}
  109. Grp2Reg        pattern    {MatchReg,AsmOprnd1,,Grp2ws2}
  110. Grp2ws2        pattern    {spancset,WhiteSpace,Grp2Comma,Grp2Comma}
  111. Grp2Comma    pattern    {MatchChar,',',0,Grp2ws3}
  112. Grp2ws3        pattern    {spancset,WhiteSpace,Grp2Reg2,Grp2Reg2}
  113. Grp2Reg2    pattern    {MatchReg,AsmOprnd2,,Grp2ws4}
  114. Grp2ws4        pattern    {spancset,WhiteSpace,Grp2Comma2,Grp2Comma2}
  115. Grp2Comma2    pattern    {MatchChar,',',0,Grp2ws5}
  116. Grp2ws5        pattern    {spancset,WhiteSpace,Grp2Op3,Grp2Op3}
  117. Grp2Op3        pattern    {ConstPat,,,EndOfLine}
  118.  
  119.  
  120. ; Patterns for the IFEQ, IFLT, and IFGT instructions.
  121.  
  122. IFEQPat        pattern    {MatchStr,IFEQInstr2}
  123. IFEQInstr2    byte    "IFEQ",0
  124.  
  125. IFLTPat        pattern    {MatchStr,IFLTInstr2}
  126. IFLTInstr2    byte    "IFLT",0
  127.  
  128. IFGTPat        pattern    {MatchStr,IFGTInstr2}
  129. IFGTInstr2    byte    "IFGT",0
  130.  
  131.  
  132. ; Grp3 Patterns:
  133.  
  134. Grp3        pattern    {sl_Match2,Grp3Strs, Grp4 ,Grp3Oprnds}
  135. Grp3Strs    pattern    {TryGet,,Grp3Put}
  136. Grp3Put        pattern    {TryPut,,Grp3GOTO}
  137. Grp3Goto    pattern    {TryGOTO}
  138.  
  139.  
  140. ; Patterns for the GET and PUT instructions.
  141.  
  142. GetPat        pattern    {MatchStr,GetInstr2}
  143. GetInstr2    byte    "GET",0
  144.  
  145. PutPat        pattern    {MatchStr,PutInstr2}
  146. PutInstr2    byte    "PUT",0
  147.  
  148. GOTOPat        pattern    {MatchStr,GOTOInstr2}
  149. GOTOInstr2    byte    "GOTO",0
  150.  
  151.  
  152.  
  153. ; Patterns for the group three (PUT/GET/GOTO) instruction operands:
  154.  
  155. Grp3Oprnds    pattern    {spancset,WhiteSpace,Grp3Op,Grp3Op}
  156. Grp3Op        pattern    {MatchGen,,,EndOfLine}
  157.  
  158.  
  159. ; Patterns for the group four instruction (HALT).
  160.  
  161. Grp4        pattern    {TryHalt,,,EndOfLine}
  162.  
  163. HaltPat        pattern    {MatchStr,HaltInstr2}
  164. HaltInstr2    byte    "HALT",0
  165.  
  166.  
  167.  
  168.  
  169. ; Patterns to match the four non-register addressing modes:
  170.  
  171. BXIndrctPat    pattern    {MatchStr,BXIndrctStr}
  172. BXIndrctStr    byte    "[BX]",0
  173.  
  174. BXIndexedPat    pattern    {ConstPat,,,BXIndrctPat}
  175.  
  176. DirectPat    pattern    {MatchChar,'[',,DP2}
  177. DP2        pattern    {ConstPat,,,DP3}
  178. DP3        pattern    {MatchChar,']'}
  179.  
  180. ImmediatePat    pattern    {ConstPat}
  181.  
  182. ; Pattern to match a hex constant:
  183.  
  184. HexConstPat    pattern    {Spancset, xdigits}
  185.  
  186.  
  187.  
  188.  
  189. dseg        ends
  190.  
  191.  
  192. cseg        segment    para public 'code'
  193.         assume    cs:cseg, ds:dseg
  194.  
  195. store        macro    Where, What
  196.         push    ds
  197.         push    ax
  198.         mov    ax, seg Where
  199.         mov    ds, ax
  200.         mov    Where, What
  201.         pop    ax
  202.         pop    ds
  203.         endm
  204.  
  205.  
  206. ; Pattern matching routines for the assembler.
  207.  
  208. ; Compare against the "LOAD" string.
  209.  
  210. TryLoad        proc    far
  211.         push    dx
  212.         push    si
  213.         ldxi    LoadPat
  214.         match2
  215.         jnc    NoTLMatch
  216.  
  217.         store    AsmOpcode, 0
  218.  
  219. NoTLMatch:    pop    si
  220.         pop    dx
  221.         ret
  222. TryLoad        endp
  223.  
  224.  
  225.  
  226. ; Compare against the "STORE" string.
  227.  
  228. TryStore    proc    far
  229.         push    dx
  230.         push    si
  231.         ldxi    StorePat
  232.         match2
  233.         jnc    NoTSMatch
  234.         store    AsmOpcode, 1
  235.  
  236. NoTSMatch:    pop    si
  237.         pop    dx
  238.         ret
  239. TryStore    endp
  240.  
  241.  
  242. ; Compare against the "ADD" string.
  243.  
  244. TryAdd        proc    far
  245.         push    dx
  246.         push    si
  247.         ldxi    AddPat
  248.         match2
  249.         jnc    NoTAMatch
  250.         store    AsmOpcode, 2
  251.  
  252. NoTAMatch:    pop    si
  253.         pop    dx
  254.         ret
  255. TryAdd        endp
  256.  
  257.  
  258. ; Compare against the "SUB" string.
  259.  
  260. TrySub        proc    far
  261.         push    dx
  262.         push    si
  263.         ldxi    SubPat
  264.         match2
  265.         jnc    NoTMMatch
  266.         store    AsmOpcode, 3
  267.  
  268. NoTMMatch:    pop    si
  269.         pop    dx
  270.         ret
  271. TrySub        endp
  272.  
  273.  
  274.  
  275. ; Compare against the "IFEQ" string.
  276.  
  277. TryIFEQ        proc    far
  278.         push    dx
  279.         push    si
  280.         ldxi    IFEQPat
  281.         match2
  282.         jnc    NoIEMatch
  283.         store    AsmOpcode, 4
  284.  
  285. NoIEMatch:    pop    si
  286.         pop    dx
  287.         ret
  288. TryIFEQ        endp
  289.  
  290.  
  291.  
  292. ; Compare against the "IFLT" string.
  293.  
  294. TryIFLT        proc    far
  295.         push    dx
  296.         push    si
  297.         ldxi    IFLTPat
  298.         match2
  299.         jnc    NoILMatch
  300.         store    AsmOpcode, 5
  301.  
  302. NoILMatch:    pop    si
  303.         pop    dx
  304.         ret
  305. TryIFLT        endp
  306.  
  307.  
  308. ; Compare against the "IFGT" string.
  309.  
  310. TryIFGT        proc    far
  311.         push    dx
  312.         push    si
  313.         ldxi    IFGTPat
  314.         match2
  315.         jnc    NoIGMatch
  316.         store    AsmOpcode, 6
  317.  
  318. NoIGMatch:    pop    si
  319.         pop    dx
  320.         ret
  321. TryIFGT        endp
  322.  
  323.  
  324.  
  325.  
  326. ; Compare against the "GET" string.
  327.  
  328. TryGET        proc    far
  329.         push    dx
  330.         push    si
  331.         ldxi    GetPat
  332.         match2
  333.         jnc    NoGMatch
  334.         store    AsmOpcode, 7
  335.         store    AsmOprnd1, 2
  336.  
  337. NoGMatch:    pop    si
  338.         pop    dx
  339.         ret
  340. TryGET        endp
  341.  
  342.  
  343.  
  344.  
  345. ; Compare against the "PUT" string.
  346.  
  347. TryPut        proc    far
  348.         push    dx
  349.         push    si
  350.         ldxi    PutPat
  351.         match2
  352.         jnc    NoPMatch
  353.         store    AsmOpcode, 7
  354.         store    AsmOprnd1, 3
  355.  
  356. NoPMatch:    pop    si
  357.         pop    dx
  358.         ret
  359. TryPUT        endp
  360.  
  361.  
  362.  
  363.  
  364. ; Compare against the "GOTO" string.
  365.  
  366. TryGOTO        proc    far
  367.         push    dx
  368.         push    si
  369.         ldxi    GOTOPat
  370.         match2
  371.         jnc    NoGMatch
  372.         store    AsmOpcode, 7
  373.         store    AsmOprnd1, 1
  374.  
  375. NoGMatch:    pop    si
  376.         pop    dx
  377.         ret
  378. TryGOTO        endp
  379.  
  380.  
  381.  
  382.  
  383. ; Compare against the "HALT" string.
  384.  
  385. TryHalt        proc    far
  386.         push    dx
  387.         push    si
  388.         ldxi    HaltPat
  389.         match2
  390.         jnc    NoHMatch
  391.         store    AsmOpcode, 7
  392.         store    AsmOprnd1, 0
  393.         store    AsmOprnd2, 0
  394.  
  395. NoHMatch:    pop    si
  396.         pop    dx
  397.         ret
  398. TryHALT        endp
  399.  
  400.  
  401.  
  402.  
  403. ; MatchReg checks to see if we've got a valid register value.  On entry,
  404. ; DS:SI points at the location to store the byte opcode (0, 1, 2, or 3) for
  405. ; a reasonable register (AX, BX, CX, or DX);  ES:DI points at the string
  406. ; containing (hopefully) the register operand, and CX points at the last
  407. ; location plus one we can check in the string.
  408. ;
  409. ; On return, Carry=1 for success, 0 for failure.  ES:AX must point beyond
  410. ; the characters which make up the register if we have a match.
  411.  
  412. MatchReg    proc    far
  413.  
  414. ; ES:DI Points at two characters which should be AX/BX/CX/DX.  Anything
  415. ; else is an error.
  416.  
  417.         cmp    byte ptr es:1[di], 'X'    ;Everyone needs this
  418.         jne    BadReg
  419.         xor    ax, ax            ;886 "AX" register code.
  420.         cmp    byte ptr es:[di], 'A'    ;AX?
  421.         je    GoodReg
  422.         inc    ax
  423.         cmp    byte ptr es:[di], 'B'    ;BX?
  424.         je    GoodReg
  425.         inc    ax
  426.         cmp    byte ptr es:[di], 'C'    ;CX?
  427.         je    GoodReg
  428.         inc    ax
  429.         cmp    byte ptr es:[di], 'D'    ;DX?
  430.         je    GoodReg
  431. BadReg:        clc
  432.         mov    ax, di
  433.         ret
  434.  
  435. GoodReg:
  436.         mov    ds:[si], al        ;Save register opcode.
  437.         lea    ax, 2[di]        ;Skip past register.
  438.         cmp    ax, cx            ;Be sure we didn't go
  439.         ja    BadReg            ; too far.
  440.         stc
  441.         ret
  442. MatchReg    endp
  443.  
  444.  
  445.  
  446. ; MatchGen-    Matches a general addressing mode.  Stuffs the appropriate
  447. ;        addressing mode code into AsmOprnd2.  If a 16-bit constant
  448. ;        is required by this addressing mode, this code shoves that
  449. ;        into the AsmConst variable.
  450.  
  451. MatchGen    proc    far
  452.         push    dx
  453.         push    si
  454.  
  455.         ldxi    Grp1Op2Reg
  456.         match2
  457.         jc    MGDone
  458.  
  459.         ldxi    BXIndrctPat
  460.         match2
  461.         jnc    TryBXIndexed
  462.         store    AsmOprnd2, 4
  463.         jmp    MGDone
  464.  
  465. TryBXIndexed:
  466.         ldxi    BXIndexedPat
  467.         match2
  468.         jnc    TryDirect
  469.         store    AsmOprnd2, 5
  470.         jmp    MGDone
  471.  
  472. TryDirect:
  473.         ldxi    DirectPat
  474.         match2
  475.         jnc    TryImmediate
  476.         store    AsmOprnd2, 6
  477.         jmp    MGDone
  478.  
  479. TryImmediate:
  480.         ldxi    ImmediatePat
  481.         match2
  482.         jnc    MGDone
  483.         store    AsmOprnd2, 7
  484.  
  485. MGDone:
  486.         pop    si
  487.         pop    dx
  488.         ret
  489. MatchGen    endp
  490.  
  491.  
  492.  
  493. ; ConstPat-    Matches a 16-bit hex constant.  If it matches, it converts
  494. ;        the string to an integer and stores it into AsmConst.
  495.  
  496. ConstPat    proc    far
  497.         push    dx
  498.         push    si
  499.         ldxi    HexConstPat
  500.         match2
  501.         jnc    CPDone
  502.  
  503.         push    ds
  504.         push    ax
  505.         mov    ax, seg AsmConst
  506.         mov    ds, ax
  507.         atoh
  508.         mov    AsmConst, ax
  509.         pop    ax
  510.         pop    ds
  511.         stc
  512.  
  513. CPDone:        pop    si
  514.         pop    dx
  515.         ret
  516. ConstPat    endp
  517.  
  518.  
  519.  
  520. ; Assemble-    This code assembles the instruction that ES:DI points
  521. ;        at and displays the hex opcode(s) for that instruction.
  522.  
  523. Assemble    proc    near
  524.         print
  525.         byte    "Assembling: ",0
  526.         strupr
  527.         puts
  528.         putcr
  529.  
  530.         ldxi    InstrPat
  531.         xor    cx, cx
  532.         match
  533.         jnc    SyntaxError
  534.  
  535. ; Quick check for illegal instructions:
  536.  
  537.         cmp    AsmOpcode, 7        ;Special/Get instr.
  538.         jne    TryStoreInstr
  539.         cmp    AsmOprnd1, 2        ;GET opcode
  540.         je    SeeIfImm
  541.         cmp    AsmOprnd1, 1        ;Goto opcode
  542.         je    IsGOTO
  543.  
  544. TryStoreInstr:    cmp    AsmOpcode, 1        ;Store Instruction
  545.         jne    NotStoreInstr
  546.  
  547. SeeIfImm:    cmp    AsmOprnd2, 7        ;Immediate Addressing Mode
  548.         jne    NotStoreInstr
  549.         print
  550.         db    "Syntax error: store/get immediate not allowed."
  551.         db    "  Try Again",cr,lf,0
  552.         jmp    ASMDone
  553.  
  554. IsGOTO:        cmp    AsmOprnd2, 7        ;Immediate mode for GOTO
  555.         je    InstrOkay
  556.         print
  557.         db    "Syntax error: GOTO only allows immediate mode.",cr,lf
  558.         db    0
  559.         jmp    ASMDone
  560.  
  561. NotStoreInstr:
  562.  
  563. InstrOkay:    mov    al, AsmOpcode
  564.         shl    al, 1
  565.         shl    al, 1
  566.         or    al, AsmOprnd1
  567.         shl    al, 1
  568.         shl    al, 1
  569.         shl    al, 1
  570.         or    al, AsmOprnd2
  571.         puth
  572.         cmp    AsmOpcode, 4        ;IFEQ instruction
  573.         jb    SimpleInstr
  574.         cmp    AsmOpcode, 6        ;IFGT instruction
  575.         jbe    PutConstant
  576.  
  577. SimpleInstr:    cmp    AsmOprnd2, 5
  578.         jb      ASMDone
  579. PutConstant:    mov    al, ' '
  580.         putc
  581.         mov    ax, ASMConst
  582.         puth
  583.         mov    al, ' '
  584.         putc
  585.         xchg    al, ah
  586.         puth
  587.         jmp    ASMDone
  588.  
  589. SyntaxError:    print
  590.         db    "Syntax error in instruction."
  591.         db    cr,lf,0
  592.  
  593.  
  594. ASMDone:    putcr
  595.         ret
  596. Assemble    endp
  597.  
  598.  
  599.  
  600.  
  601.  
  602. Main        proc
  603.         mov    ax, seg dseg        ;Set up the segment registers
  604.         mov    ds, ax
  605.         mov    es, ax
  606.         meminit
  607.  
  608.  
  609.         lesi    Str1
  610.         call    Assemble
  611.         lesi    Str2
  612.         call    Assemble
  613.         lesi    Str3
  614.         call    Assemble
  615.         lesi    Str4
  616.         call    Assemble
  617.         lesi    Str5
  618.         call    Assemble
  619.         lesi    Str6
  620.         call    Assemble
  621.         lesi    Str7
  622.         call    Assemble
  623.         lesi    Str8
  624.         call    Assemble
  625.         lesi    Str9
  626.         call    Assemble
  627.         lesi    Str10
  628.         call    Assemble
  629.         lesi    Str11
  630.         call    Assemble
  631.         lesi    Str12
  632.         call    Assemble
  633.         lesi    Str13
  634.         call    Assemble
  635.         lesi    Str14
  636.         call    Assemble
  637.  
  638.  
  639. Quit:        ExitPgm
  640. Main        endp
  641. cseg        ends
  642.  
  643. sseg        segment    para stack 'stack'
  644. stk        db    256 dup ("stack   ")
  645. sseg        ends
  646.  
  647. zzzzzzseg    segment    para public 'zzzzzz'
  648. LastBytes    db    16 dup (?)
  649. zzzzzzseg    ends
  650.         end    Main
  651.  
  652.  
  653.